home *** CD-ROM | disk | FTP | other *** search
- .\" XXX standard disclaimer belongs here....
- .\" $Header: /private/postgres/ref/postquel/RCS/defineoperator,v 1.10 1992/07/14 05:54:17 ptong Exp $
- .SP "DEFINE OPERATOR" COMMANDS 6/14/90
- .XA 2 "Define Operator"
- .uh NAME
- .lp
- define operator \*- define a new user operator
- .uh SYNOPSIS
- .lp
- .(l
- \fBdefine operator\fR operator_name
- \fB(\fR \fBarg1\fR \fB=\fR type-1
- [ \fB,\fR \fBarg2\fR \fB=\fR type-2 ]
- , \fBprocedure =\fR func_name
- [\fB, precedence =\fR number ]
- [\fB, associativity =\fR \fB(left | right | none | any)\fR ]
- [\fB, commutator =\fR com_op ]
- [\fB, negator =\fR neg_op ]
- [\fB, restrict =\fR res_proc ]
- [\fB, hashes\fR]
- [\fB, join =\fR join_proc ]
- [\fB, sort =\fR sor_op1 {\fB,\fR sor_op2 } ]
- \fB)\fR
- .\" \fB"arg is ("
- .\" type [
- .\" \fB,
- .\" type ]
- .\" \fB)
- .)l
- .uh DESCRIPTION
- .lp
- This command defines a new user operator,
- .i "operator_name" .
- The user who defines an operator becomes its owner.
- .lp
- The name of the operator,
- .i operator_name ,
- can be composed of symbols only.
- Also, the
- .i func_name
- procedure
- must have been previously defined using
- .b "define function"
- and must have one
- or two arguments.
- The types of the arguments for the operator
- and the type of the
- answer are as defined by the function.
- .b Precedence
- refers to the order that multiple instances of the same
- operator are evaluated.
- .\" what does this number mean and what is its range?
- The next several fields are primarily for the use of the query optimizer.
- .lp
- The
- .b associativity
- value is used to indicate how an expression containing
- this operator should be evaluated when precedence
- and explicit grouping are insufficient to produce
- a complete order of evaluation.
- .b Left
- and
- .b right
- indicate that expressions containing
- the operator are to be evaluated from left to right or
- from right to left, respectively.
- .b None
- means that it is an error for
- this operator to be used without
- explicit grouping when there is ambiguity.
- And
- .b any ,
- the default,
- indicates that the optimizer may choose to evaluate
- an expression which contains this operator arbitrarily.
- .lp
- .\" that multiple instances of the
- .\" operator must be be evaluated
- .\" For example, consider the area-intersection operator,
- .\" .q A,
- .\" and the following expression:
- .\" .(l
- .\" MYBOXES2.description A \*(lq0,0,1,1\*(rq A MYBOXES.description
- .\" .)l
- .\" .in .5i
- .\" The associativity flag indicates that
- .\" .(l
- .\" (MYBOXES2.description A \*(lq0,0,1,1\*(rq) A MYBOXES.description
- .\" .)l
- .\" .in .5i
- .\" is the same as
- .\" .(l
- .\" MYBOXES2.description A (\*(lq0,0,1,1\*(rq A MYBOXES.description).
- .\" .)l
- The commutator operator is present so that \*(PP can reverse
- the order of the operands if it wishes.
- For example, the operator area-less-than, >>>,
- would have a commutator operator, area-greater-than, <<<.
- Suppose that an operator, area-equal, ===, exists, as well as an area
- not equal, !==. Hence, the query optimizer could freely convert:
- .(l
- .ft C
- "0,0,1,1"::box >>> MYBOXES.description
- .ft
- .)l
- .in .5i
- to
- .(l
- .ft C
- MYBOXES.description <<< "0,0,1,1"::box
- .ft
- .)l
- .in .5i
- This allows the execution code to always use the latter representation
- and simplifies the query optimizer somewhat.
- .sp
- The negator operator allows the query optimizer to convert
- .(l
- .ft C
- not MYBOXES.description === "0,0,1,1"::box
- .ft
- .)l
- .in .5i
- to
- .(l
- .ft C
- MYBOXES.description !== "0,0,1,1"::box
- .ft
- .)l
- .in .5i
- .sp
- If a commutator operator name is supplied,
- \*(PP searches for it in the catalog.
- If it is found and it does not yet have a commutator itself,
- then the commutator's entry is updated to have the
- current (new) operator as its commutator.
- This applies to the negator,
- as well.
- .sp
- This is to allow the definition of two operators that are the
- commutators or the negators of each other.
- The first operator should be defined without a commutator or
- negator (as appropriate).
- When the second operator is defined,
- name the first as the commutator or negator.
- The first will be updated as a side effect.
- .sp
- The next two specifications are present to support the query optimizer
- in performing joins.
- \*(PP can always evaluate a
- join (i.e., processing a clause with two tuple variables separated by
- an operator that returns a boolean) by iterative substitution [WONG76].
- In addition,
- \*(PP is planning on implementing a hash-join
- algorithm along the lines of [SHAP86]; however, it must know whether this
- strategy is applicable. For example, a hash-join algorithm is usable for
- a clause of the form:
- .(l
- .ft C
- MYBOXES.description === MYBOXES2.description
- .ft
- .)l
- .in .5i
- but not for a clause of the form:
- .(l
- .ft C
- MYBOXES.description <<< MYBOXES2.description.
- .ft
- .)l
- .in .5i
- The
- .i hashes
- flag gives the needed information to the query optimizer
- concerning whether a hash join strategy is usable for the operator
- in question.
- .sp
- Similarly, the two sort
- operators indicate to the query optimizer whether merge-sort is a
- usable join strategy
- and what operators should be used to
- sort the two operand classes.
- For the === clause above, the optimizer must
- sort both relations using the operator, <<<.
- On the other hand, merge-sort is not usable with the clause:
- .(l
- .ft C
- MYBOXES.description <<< MYBOXES2.description
- .ft
- .)l
- If other join strategies are found to be practical,
- \*(PP will change
- the optimizer and run-time system to use them and
- will require additional specification
- when an operator is defined.
- Fortunately, the research community invents new join strategies infrequently,
- and the added generality of user-defined join strategies was not felt to
- be worth the complexity involved.
- .lp
- The last two pieces of the specification are present so the query
- optimizer can estimate result sizes. If a clause of the form:
- .(l
- .ft C
- MYBOXES.description <<< "0,0,1,1"::box
- .ft
- .)l
- .in .5i
- is present in the qualification,
- then \*(PP may have to
- estimate the fraction of the instances in MYBOXES
- that satisfy the clause. The function res_proc must
- be a registered function (meaning it is already defined using
- .b "define function"
- )
- which accepts one argument of the correct
- data type and returns a floating point number. The query optimizer
- simply calls this function, passing the parameter
- .ft C
- "0,0,1,1"
- .ft
- and multiplies the result by the relation size to get the desired expected
- number of instances.
- .sp
- Similarly, when the operands of the operator both contain instance variables,
- the query optimizer must estimate the size of the resulting join.
- The function join_proc will return another
- floating point number which will be multiplied by the cardinalities of the two
- classes involved to compute the desired expected result size.
- .sp
- The difference between the function
- .(l
- .ft C
- my_procedure_1 (MYBOXES.description, "0,0,1,1"::box)
- .ft
- .)l
- .in .5i
- and the operator
- .(l
- .ft C
- MYBOXES.description === "0,0,1,1"::box
- .ft
- .)l
- .in .5i
- is that \*(PP attempts to optimize operators and can decide to
- use an index to restrict the search space when operators are involved.
- However, there is no attempt to optimize functions, and they are performed
- by brute force. Moreover, functions can have any number of arguments
- while operators are restricted to one or two.
- .sp
- .(b
- .uh EXAMPLE
- .lp
- .nf
- .ft C
- /* The following command defines a new operator, */
- /* area-equality, for the BOX data type. */
-
- define operator === (
- arg1 = box,
- arg2 = box,
- procedure = area_equal_procedure,
- precedence = 30,
- associativity = left,
- commutator = ===,
- negator = !==,
- restrict = area_restriction_procedure,
- hashes,
- join = area-join-procedure,
- sort = <<<, <<<)
- .\" arg is (box, box)
- .ft
- .)b
- .uh "SEE ALSO"
- .lp
- remove operator(commands),
- define function(commands).
- .uh BUGS
- .lp
- Operator names cannot be composed of alphabetic characters in Version \*(PV.
- .lp
- Operator precedence and associativity are not implemented in Version \*(PV.
-